﻿namespace AjLogo.Language
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;

    public class Procedure : IProcedure
    {
        public Procedure(IExpression expression, Collection<string> parameterNames)
        {
            this.Expression = expression;

            if (parameterNames != null)
            {
                this.ParameterNames = new ReadOnlyCollection<string>(parameterNames);
            }
        }

        public ReadOnlyCollection<string> ParameterNames { get; private set; }

        public IExpression Expression { get; private set; }

        public int Arity
        {
            get
            {
                if (this.ParameterNames == null)
                    return 0;

                return this.ParameterNames.Count;
            }
        }

        public object Evaluate(BindingEnvironment environment, params object[] parameters)
        {
            BindingEnvironment newEnvironment;

            if (this.Arity > 0)
            {
                newEnvironment = new BindingEnvironment(environment);

                for (int k = 0; k < this.Arity; k++)
                {
                    newEnvironment.SetValue(this.ParameterNames[k], parameters[k]);
                }
            }
            else
            {
                newEnvironment = environment;
            }

            return this.Expression.Evaluate(newEnvironment);
        }
    }
}
